/*-----------------------------------------------------------------------------
 * @file   globaldef.h
 * @brief  global define header file
 * @author WLH<wanglehui8357@163.com> Copyright (C) 2021~2099.
-----------------------------------------------------------------------------*/
#ifndef GLOBAL_DEF_H
#define GLOBAL_DEF_H

/* To turn off assertions, define the symbol NDEBUG */
#ifndef NDEBUG
#define NDEBUG
#endif

/* include headers for C Standard library */
#include <assert.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/* Specify "C" linkage to get rid of C++ name mangeling */
#ifdef __cplusplus
#define BEGIN_DECLS        extern "C" {
#define END_DECLS          }
#else
#define BEGIN_DECLS
#define END_DECLS
#endif

/* redefine data type */
typedef unsigned  char                U8;   /*  8-bit unsigned integer          */
typedef signed    char                S8;   /*  8-bit   signed integer          */
typedef unsigned  short int           U16;  /* 16-bit unsigned integer          */
typedef signed    short int           S16;  /* 16-bit   signed integer          */
typedef unsigned  long                U32;  /* 32-bit unsigned integer          */
typedef signed    long                S32;  /* 32-bit   signed integer          */
typedef unsigned  long long           U64;  /* 64-bit unsigned integer          */
typedef signed    long long           S64;  /* 64-bit   signed integer          */
typedef           float               FP32; /* 32-bit floating point            */
typedef           double              FP64; /* 64-bit floating point            */
typedef volatile unsigned  char       vU8;  /* volatile  8-bit unsigned integer */
typedef volatile signed    char       vS8;  /* volatile  8-bit   signed integer */
typedef volatile unsigned  short int  vU16; /* volatile 16-bit unsigned integer */
typedef volatile signed    short int  vS16; /* volatile 16-bit   signed integer */
typedef volatile unsigned  long       vU32; /* volatile 32-bit unsigned integer */
typedef volatile signed    long       vS32; /* volatile 32-bit   signed integer */
typedef volatile unsigned  long long  vU64; /* volatile 64-bit unsigned integer */
typedef volatile signed    long long  vS64; /* volatile 64-bit   signed integer */
typedef volatile           float      vFP32;/* volatile 32-bit floating point   */
typedef volatile           double     vFP64;/* volatile 64-bit floating point   */
typedef unsigned long long      hrt_abstime;/* Absolute time, in microsecond    */

/*-----------------------------------------------------------------------------
 * Define utility macros
-----------------------------------------------------------------------------*/
/* BIT(n) sets the bit at position "n"
 * BIT(n) is intended to be used in "OR" and "AND" expressions:
 * e.g., "(BIT(3) | BIT(7))".
 */
#define BIT8(n)                     ( ((U8)(1))<<(n))
#define BIT16(n)                    (((U16)(1))<<(n))
#define BIT32(n)                    (((U32)(1))<<(n))

#define BIT8_SET(x,n)               ((x)|=BIT8(n))
#define BIT8_TST(x,n)               (((x)&(((U8)(1))<<(n)))!=0U)
#define BIT8_CLR(x,n)               ((x)= (x)&~(((U8)(1))<<(n)))

#define BIT16_SET(x,n)              ((x)|=BIT16(n))
#define BIT16_TST(x,n)              (((x)&(((U16)(1))<<(n)))!=0U)
#define BIT16_CLR(x,n)              ((x)= (x)&~(((U16)(1))<<(n)))

#define BIT32_SET(x,n)              ((x)|=BIT32(n))
#define BIT32_TST(x,n)              (((x)&(((U32)(1))<<(n)))!=0U)
#define BIT32_CLR(x,n)              ((x)= (x)&~(((U32)(1))<<(n)))

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a)               (sizeof(a)/sizeof((a)[0]))
#endif

#define BYTE_LO(a)                  ((U8)((a)&0x0Fu))
#define BYTE_HI(a)                  ((U8)((a)&0xF0u)>>4)

#define WORD_LO(a)                  ((U8)((U16)(a)))
#define WORD_HI(a)                  ((U8)((U16)(a) >> 8U))

#define DWORD_B1(a)                 ((U8)((a)        & 0xFFu))
#define DWORD_B2(a)                 ((U8)(((a)>> 8u) & 0xFFu))
#define DWORD_B3(a)                 ((U8)(((a)>>16u) & 0xFFu))
#define DWORD_B4(a)                 ((U8)(((a)>>24u) & 0xFFu))

#define GEN_WORD(lo,hi)             ((U16)((lo)+((U16)(hi)<<8u)))
#define GEN_WORD_S(lo,hi)           ((S16)GEN_WORD(lo, hi))

static inline U32 GEN_U32(const U8 a, const U8 b, const U8 c, const U8 d)
{
    return ((U32)d << 24u) | ((U32)c << 16u) | ((U32)b <<  8u) | (U32)a;
}

#define GEN_S32(a,b,c,d)            ((S32)GEN_U32(a,b,c,d))

#define U32_TO_BUF(val, buf, oft)   do {\
                                        (buf)[(oft)+0u]=DWORD_B1((val)); \
                                        (buf)[(oft)+1u]=DWORD_B2((val)); \
                                        (buf)[(oft)+2u]=DWORD_B3((val)); \
                                        (buf)[(oft)+3u]=DWORD_B4((val)); \
                                    }while(0)

#define BUF_TO_U32(buf, oft)        ((U32)(((U32)(buf)[0u+(oft)])      |\
                                           ((U32)(buf)[1u+(oft)])<< 8u |\
                                           ((U32)(buf)[2u+(oft)])<<16u |\
                                           ((U32)(buf)[3u+(oft)])<<24u))

#define S32_TO_BUF(buf, oft)        ((S32)U32_TO_BUF((buf), (oft)))
#define BUF_TO_S32(buf, oft)        ((S32)BUF_TO_U32((buf), (oft)))

static inline void BUF_TO_FP32(const U8* buf, unsigned oft, FP32* val)
{
    U8* dst_ptr = (U8*)val;
    dst_ptr[0u] = buf[0u+oft];
    dst_ptr[1u] = buf[1u+oft];
    dst_ptr[2u] = buf[2u+oft];
    dst_ptr[3u] = buf[3u+oft];
}

/* to avoid compiler warnings */
#ifndef UNUSED
#define UNUSED(v)   ((void)(v))
#endif

/*-----------------------------------------------------------------------------
 * Compilers dependant keywords
-----------------------------------------------------------------------------*/
#if defined   (__CC_ARM)   /* Keil µVision 4    */
    #define ALIGNED(a)      __attribute__((__aligned__(a)))
    #define PACKED_STRUCT   struct __attribute__((packed))
    #define PACK_BEGIN
    #define PACK_END
    #define PUT_SECTION(a) __attribute__ ((section (a)))
#elif defined (__ICCARM__) /* IAR EWARM 5.41+   */
    #define X_PRAGMA(arg)   _Pragma(#arg)
    #define ALIGNED(a)      X_PRAGMA(data_alignment=a)
    #define PACKED_STRUCT   __packed struct
    #define PACK_BEGIN
    #define PACK_END
    #define PUT_SECTION(a)  X_PRAGMA(location=a)
#elif defined (__GNUC__)   /* GCC CS3 2009q3-68 */
    #define ALIGNED(a)      __attribute__((__aligned__(a)))
    #define PACKED_STRUCT   struct __attribute__((packed))
    #define PACK_BEGIN
    #define PACK_END
    #define PUT_SECTION(a) __attribute__ ((section (a)))
#elif defined(_MSC_VER)
    #define ALIGNED(a)
    #define PACKED_STRUCT   struct
    #define PACK_BEGIN      __pragma(pack(push, 1))
    #define PACK_END        __pragma(pack(pop))
    #define PUT_SECTION(a)
#endif

#endif//~GLOBAL_DEF_H
